package com.oceansoft.mobile.econsole.scheduled;

import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.oceansoft.mobile.econsole.common.util.HttpClientUtil;
import com.oceansoft.mobile.econsole.modules.sys.entity.ApiInfo;
import com.oceansoft.mobile.econsole.modules.sys.entity.ApiMonitorLog;
import com.oceansoft.mobile.econsole.modules.sys.entity.ApiMonitorSMS;
import com.oceansoft.mobile.econsole.modules.sys.entity.ParamInfo;
import com.oceansoft.mobile.econsole.modules.sys.service.IApiInfoService;
import com.oceansoft.mobile.econsole.modules.sys.service.IParamService;
import com.oceansoft.mobile.econsole.task.sms.SMSUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

public class ScheduleTasker {

	private Logger logger = LoggerFactory.getLogger(ScheduleTasker.class
			.getName());
	private int mCounter; // 任务调度次数计数器
	private int corePoolSize = 10;
	private ApiInfo apiInfo;
	private List<ParamInfo> params;
	private IApiInfoService apiInfoService;
	private IParamService paramService;

	 
	private static Map<String,ScheduledThreadPoolExecutor> ScheduleTaskerMap = new HashMap<String,ScheduledThreadPoolExecutor>();

	public ScheduleTasker(ApiInfo apiInfo, List<ParamInfo> params,
			IApiInfoService apiInfoService, IParamService paramService) {
		this.apiInfoService = apiInfoService;
		this.paramService = paramService;
		this.apiInfo = apiInfo;
		this.params = params;
		this.mCounter = 0;
	}
	//更新调用的线程构造器
	public ScheduleTasker(ApiInfo apiInfo,IApiInfoService apiInfoService, IParamService paramService) {
		this.apiInfoService = apiInfoService;
		this.paramService = paramService;
		this.apiInfo = apiInfo;
		this.mCounter = 0;
		//之前线程未关闭，又重新开启一个线程，导致记录重复。
		
	}
	/**
	 * 启动主任务定时器
	 */
	public void startTask() {
		
		ScheduledThreadPoolExecutor mainTask = new ScheduledThreadPoolExecutor(corePoolSize);
		ScheduleTaskerMap.put(apiInfo.getId()+"",mainTask);
		ScheduledFuture  v  =  mainTask.scheduleWithFixedDelay(new Runnable() {
			public void run() {
			getMonitorStatus();
			}
		},0,apiInfo.getTimeInterval(),TimeUnit.MINUTES);
		
	}
	
	public void reloadMonit(int id)
	{
		ScheduledThreadPoolExecutor mainTask = ScheduleTaskerMap.get(id+"");
		mainTask.shutdown();
	//ScheduleTaskerMap.put(apiInfo.getId()+"",mainTask);
	}
	
	public void getMonitorStatus() {
		//apiInfo对象接口状态有可能改变，所有需要重新查询
		apiInfo = apiInfoService.findApiBaseInfoById(apiInfo.getId());
		if(apiInfo == null)
			return;
		params = paramService.findAllParams(apiInfo.getId());
		if (apiInfo.getStatus() == 0) {
			logger.info("============="+apiInfo.getApiName()+"接口已经禁用================");
			return;
		}
		Date start = new Date();
		logger.info("============="+apiInfo.getApiName()+"接口监控开始================");
		// 等于容错次数,接口异常
		if (mCounter >= apiInfo.getErrorNum()) {
			mCounter++;
			apiInfo.setStatus(-1);
			apiInfoService.updateApiInfo(apiInfo);
			//时间间隔内是否发送过短信
			int count = apiInfoService.alreadyHasSMS(apiInfo);
			if(count == 0){
				String msg = apiInfo.getApiName()+"异常，请检查！";
			//	SMSUtil.sendSMS("jk"+apiInfo.getId(), msg, apiInfo.getPhone());
				ApiMonitorSMS sms = new ApiMonitorSMS(apiInfo.getId(),new Date(),apiInfo.getPhone());
				apiInfoService.saveApiMonitorSMS(sms);
				logger.info("================发送短信===============");
			}
		}
		String rt = null;
		if (apiInfo.getIsPost() == 0) {
			try {
				Map<String, String> map = transferList2Map(params);
				String getUrl = processGetParams(apiInfo.getUrl(), map, "UTF-8");
				rt = HttpClientUtil.doGet(getUrl);
				// 响应正常容错为0
				mCounter = 0;
				apiInfo.setStatus(1);
				apiInfoService.updateApiInfo(apiInfo);
			} catch (IllegalArgumentException e) {
				rt = e.getMessage();
			} catch (IOException e) {
				rt = e.getMessage();
				// 出现异常时进行容错查询
				mCounter++;
			}
		} else {
			Map<String, String> map = transferList2Map(params);
			rt = HttpClientUtil.doPost(apiInfo.getUrl(), map, "UTF-8");
			if (rt == null) {
				rt = "接口异常";
				mCounter++;
			} else {
				// 响应正常容错为0
				mCounter = 0;
				apiInfo.setStatus(1);
				apiInfoService.updateApiInfo(apiInfo);
			}
		}
		int status = (mCounter==0 ? 1 : -1);
		String resp = (mCounter==0 ? "正常" : "异常"); 
		int responseTime = (int) (new Date().getTime() - start.getTime());
		ApiMonitorLog log = new ApiMonitorLog(start, resp, responseTime, status,apiInfo.getId());
		apiInfoService.saveApiMonitorLog(log);
		logger.info("============"+apiInfo.getApiName()+"接口"+resp+",响应时间为"+responseTime+"==================");
	}

	/**
	 * list中的对象转换为map
	 * 
	 * @param list
	 * @return
	 */
	private Map<String, String> transferList2Map(List<ParamInfo> list) {
		Map<String, String> map = new HashMap<String, String>();
		for (ParamInfo info : list) {
			map.put(info.getParamName(), info.getParamValue());
		}
		return map;
	}

	/**
	 * 处理get请求
	 * 
	 * @param url
	 * @param params
	 * @param charset
	 * @return
	 * @throws IOException
	 */
	private String processGetParams(String url, Map<String, String> params,
			String charset) throws IOException {
		if (params != null && !params.isEmpty()) {
			List<NameValuePair> pairs = new ArrayList<NameValuePair>(
					params.size());
			for (Map.Entry<String, String> entry : params.entrySet()) {
				String value = entry.getValue();
				if (value != null) {
					pairs.add(new BasicNameValuePair(entry.getKey(), value));
				}
			}
			url += "?"
					+ EntityUtils.toString(new UrlEncodedFormEntity(pairs,
							charset));
		}
		return url;
	}

}
